import DataBus from './databus'
import GameInfo from './runtime/gameinfo'
import Background from './runtime/background'
import Board from './runtime/board'
import ConfirmDialog from './runtime/confirmDialog'
import MainMenu from './runtime/mainMenu'
import OnlineMenu from './runtime/onlineMenu'
import AIMenu from './runtime/aiMenu'
import GameControlPanel from './runtime/gameControlPanel'

import GameAI from './ai/gameAI'
import DeviceDetector from './utils/deviceDetector'
import ErrorHandler from './utils/errorHandler'

// 启动前安全检查
function performStartupChecks() {
  console.log('开始启动安全检查...');
  
  // 检查微信环境
  if (typeof wx !== 'undefined') {
    console.log('微信环境检测成功');
  } else {
    console.warn('微信环境不可用');
  }
  
  // 检查游戏子包环境
  const isGameSubContext = typeof GameGlobal !== 'undefined' && GameGlobal.IS_GAME_SUB_CONTEXT;
  if (isGameSubContext) {
    console.log('检测到游戏子包环境');
  } else {
    console.log('检测到页面环境');
  }
  
  // 检查全局对象
  if (typeof GameGlobal !== 'undefined') {
    console.log('GameGlobal对象可用');
  } else {
    console.warn('GameGlobal对象不可用');
  }
  
  console.log('启动安全检查完成');
}

// 执行启动检查
performStartupChecks();

// 安全地获取Canvas上下文 - 小程序环境适配
let ctx = null;
let canvas = null;

// 在小程序环境中，Canvas由页面提供，不在这里创建
console.log('Canvas将在页面中初始化');

let databus = new DataBus()
let gameinfo = new GameInfo()
let background = new Background()
let board = new Board()
let confirmDialog = new ConfirmDialog()
let mainMenu = new MainMenu()
let onlineMenu = new OnlineMenu()
let aiMenu = new AIMenu()
let gameControlPanel = new GameControlPanel()

let gameAI = new GameAI()

export default class Main {
  constructor(canvasParam = null, ctxParam = null) {
    // 安全地设置Canvas - 优先使用传入的参数
    try {
      if (canvasParam && ctxParam) {
        this.canvas = canvasParam;
        this.ctx = ctxParam;
        console.log('使用传入的Canvas参数');
      } else {
        this.canvas = canvas;
        this.ctx = ctx;
        console.log('使用默认Canvas');
      }
    } catch (error) {
      console.warn('Canvas引用失败:', error);
      this.canvas = null;
      this.ctx = null;
    }
    
    // 绑定触摸事件
    this.bindTouchEvents()
    
    // 初始化游戏状态
    this.init()
  }

  init() {
    // 设置全局错误处理
    this.setupErrorHandling()
    
    // 记录设备信息
    DeviceDetector.logDeviceInfo()
    
    databus.reset()
    board.init()
    confirmDialog.hide()
    
    // 设置主菜单回调
    mainMenu.setOfflineGameStartCallback(() => {
      this.startOfflineGame()
    })
    
    mainMenu.setAIGameStartCallback(() => {
      this.showAIMenu()
    })
    
    mainMenu.setOnlineGameStartCallback(() => {
      this.startOnlineGame()
    })
    
    // 设置AI菜单回调
    aiMenu.setAIGameStartCallback((difficulty) => {
      this.startAIGame(difficulty)
    })
    
    aiMenu.setBackToMainMenuCallback(() => {
      this.returnToMainMenu()
    })
    
    // 设置在线菜单回调
    onlineMenu.setGameStartCallback(() => {
      this.startOnlineGame()
    })
    
    onlineMenu.setRoomCreatedCallback((roomId, isHost) => {
      this.handleRoomCreated(roomId, isHost)
    })
    
    onlineMenu.setRoomJoinedCallback((roomId, isHost) => {
      this.handleRoomJoined(roomId, isHost)
    })
    
    onlineMenu.setReturnToMainMenuCallback(() => {
      this.returnToMainMenu()
    })
    
    // 设置云开发回调
    const cloudManager = onlineMenu.getCloudManager()
    if (cloudManager) {
      console.log('设置云开发回调')
      
      cloudManager.onMoveReceived = (chessboard, currentPlayer) => {
        console.log('收到对手落子:', { chessboard, currentPlayer })
        // 更新棋盘状态
        databus.board = chessboard
        
        // 检查是否轮到当前玩家
        if (currentPlayer === cloudManager.playerId) {
          databus.setMyTurn(true)
        } else {
          databus.setMyTurn(false)
        }
      }
      
      cloudManager.onGameStart = () => {
        console.log('在线游戏开始回调触发')
        databus.setOpponentConnected(true)
        databus.setGameStarted(true)
        
        // 显示游戏控制面板
        gameControlPanel.show()
        
        // 确保游戏界面可见，隐藏其他菜单
        mainMenu.hide()
        onlineMenu.hide()
        aiMenu.hide()
        
        // 重置棋盘
        board.init()
        
        console.log('游戏界面设置完成')
      }
      
      cloudManager.onGameOver = (winner) => {
        console.log('游戏结束回调触发:', winner)
        if (winner === 0) {
          // 平局
          databus.setGameOver(0)
          gameinfo.showGameOver(0, '游戏平局！')
        } else {
          const isWinner = winner === cloudManager.playerId
          const winnerPlayer = isWinner ? databus.myPlayer : (databus.myPlayer === 1 ? 2 : 1)
          databus.setGameOver(winnerPlayer)
          gameinfo.showGameOver(winnerPlayer, isWinner ? '你赢了！' : '你输了')
        }
      }
      
      cloudManager.onOpponentConnected = () => {
        console.log('对手连接回调触发')
        databus.setOpponentConnected(true)
      }
      
      cloudManager.onOpponentDisconnected = () => {
        console.log('对手断开连接回调触发')
        databus.setOpponentConnected(false)
      }
    }
    
    // 设置游戏信息回调
    gameinfo.setReturnToMenuCallback(() => {
      this.returnToMainMenu()
    })
    
    // 设置游戏控制面板回调
    gameControlPanel.setUndoCallback(() => {
      this.handleUndo()
    })
    
    gameControlPanel.setBackToMenuCallback(() => {
      this.returnToMainMenu()
    })
    
    gameControlPanel.setSurrenderCallback(() => {
      this.handleSurrender()
    })
    
    // 初始化时隐藏游戏控制面板
    gameControlPanel.hide()
    
    // 将AI实例暴露到全局，供棋盘使用
    if (typeof window !== 'undefined') {
      window.gameAI = gameAI
    } else if (typeof GameGlobal !== 'undefined') {
      // 微信小程序环境
      GameGlobal.gameAI = gameAI
    }
    
    // 检查是否从分享进入
    this.checkShareEntry()
    
    // 开始游戏循环
    this.loop()
  }

  setupErrorHandling() {
    // 设置全局错误处理 - 适配游戏子包环境
    const isGameSubContext = typeof GameGlobal !== 'undefined' && GameGlobal.IS_GAME_SUB_CONTEXT;
    
    // 检查window对象是否可用且支持addEventListener
    if (typeof window !== 'undefined' && typeof window.addEventListener === 'function' && !isGameSubContext) {
      try {
        window.addEventListener('error', (event) => {
          console.warn('全局错误:', event.error);
          ErrorHandler.handleError(event.error, '全局错误');
        });
        
        window.addEventListener('unhandledrejection', (event) => {
          console.warn('未处理的Promise拒绝:', event.reason);
          ErrorHandler.handleError(event.reason, 'Promise拒绝');
        });
      } catch (error) {
        console.warn('设置window错误处理失败:', error);
      }
    }
    
    // 微信环境错误处理
    if (typeof wx !== 'undefined') {
      try {
        if (wx.onError) {
          wx.onError((error) => {
            console.warn('微信环境错误:', error);
            ErrorHandler.handleError(error, '微信环境');
          });
        }
      } catch (error) {
        console.warn('设置微信错误处理失败:', error);
      }
    }
    
    // 游戏子包环境错误处理
    if (isGameSubContext) {
      try {
        // 在游戏子包中，使用不同的错误处理方式
        console.log('游戏子包环境错误处理已设置');
      } catch (error) {
        console.warn('设置游戏子包错误处理失败:', error);
      }
    }
  }

  checkShareEntry() {
    // 检查是否从分享链接进入 - 真机环境优化
    try {
      if (typeof wx !== 'undefined') {
        // 延迟检查，避免启动时的API调用问题
        setTimeout(() => {
          try {
            if (wx.getLaunchOptionsSync) {
              const launchOptions = wx.getLaunchOptionsSync()
              if (launchOptions && launchOptions.query && launchOptions.query.game === 'gobang') {
                // 从分享进入，直接开始游戏
                this.startOfflineGame()
              }
            }
          } catch (launchError) {
            console.warn('获取启动参数失败:', launchError);
          }
        }, 1000); // 延迟1秒检查
      }
    } catch (error) {
      console.warn('检查分享入口失败:', error);
    }
  }

  startOfflineGame() {
    mainMenu.hide()
    onlineMenu.hide()
    gameControlPanel.show()
    databus.reset()
    databus.setOnlineMode(false)
    board.init()
    confirmDialog.hide()
  }

  showAIMenu() {
    mainMenu.hide()
    aiMenu.show()
  }

  startAIGame(difficulty) {
    mainMenu.hide()
    aiMenu.hide()
    gameControlPanel.show()
    databus.reset()
          databus.setAIMode(true, difficulty, 2) // AI执黑方
    gameAI.setDifficulty(difficulty)
    
    board.init()
    confirmDialog.hide()
  }

  startOnlineGame() {
    mainMenu.hide()
    onlineMenu.show()
  }

  handleRoomCreated(roomId, isHost) {
    console.log('处理房间创建:', { roomId, isHost })
    // 房主是白子(2)，加入者是黑子(1)
    databus.setOnlineMode(true, isHost ? 2 : 1)
    databus.setRoomId(roomId)
    databus.setOpponentConnected(false)
  }

  handleRoomJoined(roomId, isHost) {
    console.log('处理房间加入:', { roomId, isHost })
    // 房主是白子(2)，加入者是黑子(1)
    databus.setOnlineMode(true, isHost ? 2 : 1)
    databus.setRoomId(roomId)
    databus.setOpponentConnected(false)
    
    // 显示游戏控制面板，准备开始游戏
    gameControlPanel.show()
  }

  handleOpponentMove(row, col, player) {
    // 处理对手的落子
    if (databus.handleOpponentMove(row, col, player)) {
      console.log('对手落子:', row, col, player)
    }
  }

  // 处理在线落子
  async handleOnlineMove(row, col) {
    const cloudManager = onlineMenu.getCloudManager()
    if (!cloudManager || !databus.isMyTurn) {
      return false
    }
    
    try {
      await cloudManager.makeMove(row, col)
      return true
    } catch (error) {
      console.error('在线落子失败:', error)
      wx.showToast({
        title: error.message || '落子失败',
        icon: 'none'
      })
      return false
    }
  }

  returnToMainMenu() {
    mainMenu.show()
    onlineMenu.hide()
    aiMenu.hide()
    gameControlPanel.hide()
    databus.reset()
    board.init()
    confirmDialog.hide()
    
    // 清理云开发资源
    const cloudManager = onlineMenu.getCloudManager()
    if (cloudManager) {
      cloudManager.cleanup()
    }
  }

  getCloudManager() {
    return onlineMenu.getCloudManager()
  }

  // 获取在线菜单实例
  getOnlineMenu() {
    return onlineMenu
  }


  handleUndo() {
    console.log('悔棋功能：撤销上一步')
    
    // 检查当前玩家是否还有悔棋次数
    const currentPlayer = databus.currentPlayer
    if (!databus.canUndo(currentPlayer)) {
      console.log('没有悔棋次数了')
      return
    }
    
    // AI模式下，只有玩家可以悔棋，AI不能悔棋
    if (databus.isAIMode && currentPlayer === databus.aiPlayer) {
      console.log('AI模式下，AI不能悔棋')
      return
    }
    
    // AI模式下的悔棋逻辑
    if (databus.isAIMode) {
      // 检查是否有足够的落子历史（至少2步：玩家+AI）
      if (databus.moveHistory.length >= 2) {
        console.log('AI模式悔棋：撤销玩家和AI的最后一步')
        
        // 使用悔棋次数
        if (databus.useUndo(currentPlayer)) {
          // 撤销两步（AI和玩家的落子）
          databus.undoAIMoves()
          
          // 清除预览
          board.clearPreview()
          
          console.log(`玩家剩余悔棋次数: ${databus.getUndoCount(currentPlayer)}`)
        }
      } else {
        console.log('AI模式悔棋：历史记录不足，无法悔棋')
      }
    } else {
      // 非AI模式下的悔棋逻辑
      if (databus.moveHistory.length > 0) {
        console.log('撤销最后一步')
        
        // 使用悔棋次数
        if (databus.useUndo(currentPlayer)) {
          // 撤销最后一步
          const success = databus.undoLastMove()
          
          if (success) {
            // 清除预览
            board.clearPreview()
            
            console.log(`${currentPlayer === 1 ? '红方' : '黑方'}剩余悔棋次数: ${databus.getUndoCount(currentPlayer)}`)
          }
        }
      } else {
        console.log('没有移动历史，无法悔棋')
      }
    }
  }

  handleSurrender() {
    console.log('结束游戏功能：当前玩家结束游戏')
    
    const currentPlayer = databus.currentPlayer
    const winner = currentPlayer === 1 ? 2 : 1 // 对手获胜
          const winnerName = winner === 1 ? '红方' : '黑方'
    
    console.log(`${winnerName}获胜！`)
    
    // 设置游戏结束状态
    databus.setGameOver(winner)
    
    // 显示游戏结束信息（不显示认输文字）
    gameinfo.showGameOver(winner)
    
    // 如果是网络对战，通知对手
    if (databus.isOnlineMode) {
      const cloudManager = onlineMenu.getCloudManager()
      if (cloudManager) {
        // 云开发环境下，结束游戏通过游戏结束状态处理
        console.log('在线结束游戏')
      }
    }
  }

  bindTouchEvents() {
    // 检查环境类型
    const isGameSubContext = typeof GameGlobal !== 'undefined' && GameGlobal.IS_GAME_SUB_CONTEXT;
    
    if (isGameSubContext) {
      // 游戏子包环境下，Canvas事件由Canvas自己处理
      console.log('游戏子包环境：Canvas事件由Canvas处理');
    } else {
      // 页面环境下依赖页面事件处理
      console.log('页面环境：触摸事件将由页面处理');
    }
  }

  bindCanvasEvents() {
    // 检查环境类型
    const isGameSubContext = typeof GameGlobal !== 'undefined' && GameGlobal.IS_GAME_SUB_CONTEXT;
    
    if (isGameSubContext) {
      // 游戏子包环境下，Canvas事件由Canvas自己处理
      console.log('游戏子包环境：Canvas事件由Canvas处理');
    } else {
      // 页面环境下不绑定Canvas事件
      console.log('页面环境：Canvas事件由页面处理');
    }
  }

  handleTouch(x, y) {
    // 如果主菜单显示，优先处理主菜单
    if (mainMenu.isVisible) {
      if (mainMenu.handleTouch(x, y)) {
        return
      }
      return
    }

    // 如果AI菜单显示，优先处理AI菜单
    if (aiMenu.isVisible) {
      if (aiMenu.handleTouch(x, y)) {
        return
      }
      return
    }

    // 如果在线菜单显示，优先处理在线菜单
    if (onlineMenu.isVisible) {
      if (onlineMenu.handleTouch(x, y)) {
        return
      }
      return
    }

    // 如果确认对话框显示，优先处理对话框（保留兼容性）
    if (confirmDialog.isVisible) {
      if (confirmDialog.handleTouch(x, y)) {
        // 确认落子
        if (confirmDialog.moveInfo) {
          board.setPendingMove(confirmDialog.moveInfo)
          board.confirmMove()
          
          // 如果是在线模式，发送落子信息
          if (databus.isOnlineMode) {
            this.handleOnlineMove(confirmDialog.moveInfo.row, confirmDialog.moveInfo.col)
          }
        }
        confirmDialog.hide()
      }
      return
    }

    // 处理游戏控制面板点击
    if (gameControlPanel.isVisible) {
      if (gameControlPanel.handleTouch(x, y)) {
        // 如果触摸到了控制面板，检查是否点击
        if (gameControlPanel.handleClick(x, y)) {
          return
        }
        return
      }
    }



    // 处理游戏结束界面的点击
    if (databus.gameOver) {
      if (gameinfo.handleTouch(x, y)) {
        return
      }
    }

    // 处理棋盘点击
    let result = board.handleTouch(x, y)
    if (result && result.moved) {
      // 在线模式下检查是否可以落子
      if (databus.isOnlineMode && !databus.canMakeMove()) {
        console.log('不是你的回合或对手未连接')
        wx.showToast({
          title: '不是你的回合',
          icon: 'none'
        })
        return
      }
      
      // 如果是在线模式，发送落子信息
      if (databus.isOnlineMode) {
        this.handleOnlineMove(result.toRow, result.toCol)
      }
      
      // 如果是AI模式，让AI下棋
      if (databus.isAIMode && !databus.gameOver) {
        setTimeout(() => {
          board.makeAIMove()
        }, 500)
      }
    }
  }

  loop() {
    databus.frame++

    this.update()
    this.render()

    // 使用setTimeout替代requestAnimationFrame，添加错误处理
    try {
      setTimeout(() => {
        this.loop()
      }, 1000 / 60) // 60fps
    } catch (error) {
      console.error('游戏循环错误:', error);
      // 如果循环出错，尝试重新启动
      setTimeout(() => {
        this.loop()
      }, 1000 / 30) // 降级到30fps
    }
  }

  update() {
    if (databus.gameOver) {
      // 游戏结束时隐藏控制面板
      if (gameControlPanel.isVisible) {
        gameControlPanel.hide()
      }
      return
    }

    background.update()
    board.update()
    confirmDialog.update()
    mainMenu.update()
    aiMenu.update()
    onlineMenu.update()
    gameControlPanel.update()
  }

  render() {
    if (!this.ctx) {
      console.warn('Canvas上下文不可用，跳过渲染');
      return;
    }
    
    try {
      // 安全地获取canvas尺寸
      const canvasWidth = this.canvas ? this.canvas.width : 375;
      const canvasHeight = this.canvas ? this.canvas.height : 667;
      
      this.ctx.clearRect(0, 0, canvasWidth, canvasHeight)

      background.render(this.ctx)
      board.render(this.ctx)
      gameinfo.render(this.ctx)
      confirmDialog.render(this.ctx)
      mainMenu.render(this.ctx)
      aiMenu.render(this.ctx)
      onlineMenu.render(this.ctx)
      
      // 游戏结束时隐藏控制面板
      if (!databus.gameOver) {
        gameControlPanel.render(this.ctx)
      }
    } catch (error) {
      console.error('渲染失败:', error);
    }
  }
}
